#include  "ota_http_curl.h"
#include  <curl/curl.h>
#include  <string.h>
#include  <stdlib.h>



/**
 * 接收数据回调
 * @param  ptr: 接收数据的指针
 * @param  size: 单个数据的大小
 * @param  nmemb: 数据个数
 * @param  userdata: 用户数据容器
 */
static  size_t ota_http_curl_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    // 1  计算数据总大小
    size_t size_all = size * nmemb;
    // 2  把用户数据容器进行强制转换 response_body_t *
    response_body_t *response_body = (response_body_t *)userdata;
    // 3  给reponse_body 的 str 开辟空间
    response_body->str = malloc(size_all + 1);
    // 4  把ptr数据拷贝到response_body->str中
    memcpy(response_body->str, ptr, size_all);
    // 5  补结束符串
    response_body->str[size_all] = '\0';
    // 6  长度 给response_body->size 
    response_body->size = size_all;
    // 7  返回数据总大小
    return size_all;
}


/**
 * @brief  根据url地址利用curl获得文本信息
 * @param  url: url地址
 * @return  返回一个结构体
 *  1 初始化curl 
 *  2 初始化 response_body_t  数据容器 用于接收结果
 *  3 设置curl的url地址、设置接收数据的回调、设置接收数据的容器
 *  4 执行访问 
 *  5 如果访问成功 返回数据容器
 *  6 如果访问失败 返回NULL
 */
response_body_t *ota_http_curl_get(char *url)
{
    // *  1 初始化curl 
    CURL *curl = curl_easy_init();
    // *  2 初始化 response_body_t  数据容器 用于接收结果
    response_body_t *response_body = malloc(sizeof(response_body_t));
    // *  3 设置curl的url地址、设置接收数据的回调、设置接收数据的容器
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ota_http_curl_write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, response_body);
    // *  4 执行访问 
    CURLcode res = curl_easy_perform(curl);
    // *  5 如果访问成功 返回数据容器
    // *  6 如果访问失败 返回NULL
    if (res != CURLE_OK)
    {
         perror("地址访问失败");
         return NULL;
    }
    return response_body;
 
}

/**
 * @brief  从远端url 下载文件
 * @param  url: url地址
 * @param  file_path: 文件保存路径
 * @return  返回 0 成功  -1失败
 */
int ota_http_curl_download(char *url, char *file_path)
{
    // *  1 初始化curl 
    CURL *curl = curl_easy_init();
    // *  2 初始化 FILE *   打开指定的路径获得文件指针
    FILE *fp = fopen(file_path, "wb");
    // *  3 设置curl的url地址、设置接收数据的回调 fwrite、设置接收文件指针 FILE * 
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
    // *  4 执行访问 
    CURLcode res = curl_easy_perform(curl);
    // *  5 关闭文件指针  重要 确保缓冲区的内容flush到磁盘中
    fclose(fp);
    // *  6 释放curl资源
    curl_easy_cleanup(curl);
    // *  7 如果访问成功 返回0
    // *  8 如果访问失败 返回-1
    if (res != CURLE_OK)
    {
         perror("下载文件失败");
         return -1;
    }
    return 0;
    

}